package com.ylsk.check.service.impl;

import java.util.Date;
import java.util.List;

import com.google.common.primitives.Longs;
import com.ylsk.check.domain.ReportInfo;
import com.ylsk.check.domain.dto.MsgTemplateDTO;
import com.ylsk.check.domain.dto.WithdrawalReportDTO;
import com.ylsk.check.domain.emum.BasicInfoTemplateEnum;
import com.ylsk.check.domain.emum.ConstructionStatusEnum;
import com.ylsk.check.domain.emum.MsgTemplateEnum;
import com.ylsk.check.domain.so.JeevesReportSO;
import com.ylsk.check.domain.so.WithdrawalReportSO;
import com.ylsk.check.domain.vo.JeevesReportVO;
import com.ylsk.check.domain.vo.WithdrawalReportVO;
import com.ylsk.check.mapper.JeevesReportMapper;
import com.ylsk.common.annotation.DataScope;
import com.ylsk.common.config.SnowIdConfig;
import com.ylsk.common.exception.ServiceException;
import com.ylsk.common.utils.DateUtils;
import com.ylsk.common.utils.Generic;
import com.ylsk.common.utils.SecurityUtils;
import com.ylsk.common.utils.StringUtils;
import com.ylsk.system.domain.FileSimple;
import com.ylsk.system.helper.FileHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ylsk.check.mapper.WithdrawalReportMapper;
import com.ylsk.check.domain.WithdrawalReport;
import com.ylsk.check.service.IWithdrawalReportService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 撤场上报Service业务层处理
 *
 * @author yangsy
 * @date 2023-12-21
 */
@Service
public class WithdrawalReportServiceImpl implements IWithdrawalReportService
{
    @Autowired
    private WithdrawalReportMapper withdrawalReportMapper;

    @Autowired
    private SnowIdConfig snowIdConfig;

    @Autowired
    private FileHelper fileHelper;

    @Autowired
    private ReportInfoHelper helper;

    @Autowired
    private JeevesReportMapper jeevesReportMapper;

    /**
     * 查询撤场上报
     *
     * @param withdrawalReportId 撤场上报主键
     * @return 撤场上报
     */
    @Override
    public WithdrawalReportVO selectWithdrawalReportByWithdrawalReportId(Long withdrawalReportId)
    {
        if(null == withdrawalReportId){
            throw new ServiceException("withdrawalReportId 不能为空!");
        }
        WithdrawalReportVO withdrawalReportVO = withdrawalReportMapper.selectWithdrawalReportByWithdrawalReportId(withdrawalReportId);
        //设置附件信息
        Long withdrawalFileId = withdrawalReportVO.getWithdrawalFileId();
        List<FileSimple> fileSimpleList =fileHelper.getFileByBusinessId(withdrawalFileId);
        withdrawalReportVO.setWithdrawalFile(fileSimpleList);
        return withdrawalReportVO;
    }

    /**
     * 查询撤场上报列表
     *
     * @param withdrawalReportSO 撤场上报
     * @return 撤场上报
     */
    @Override
    @DataScope(deptAlias = "sd",userAlias = "su")
    public List<WithdrawalReportVO> selectWithdrawalReportList(WithdrawalReportSO withdrawalReportSO)
    {
        return withdrawalReportMapper.selectWithdrawalReportList(withdrawalReportSO);
    }

    /**
     * 新增撤场上报
     *
     * @param withdrawalReportDTO 撤场上报
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertWithdrawalReport(WithdrawalReportDTO withdrawalReportDTO)
    {
        final Long jeevesReportId = withdrawalReportDTO.getJeevesReportId();
        if(null == jeevesReportId){
            throw new ServiceException("占道报备不能为空!");
        }
        final Integer endProject = withdrawalReportDTO.getEndProject();
        if(null == endProject){
            throw new ServiceException("撤场类型不能为空!");
        }
        Long reportInfoId = withdrawalReportDTO.getReportInfoId();
        if(null == reportInfoId){
            throw new ServiceException("施工报备不能为空!");
        }
        WithdrawalReport withdrawalReport = new WithdrawalReport();
        BeanUtils.copyProperties(withdrawalReportDTO,withdrawalReport);
        long withdrawalReportId = snowIdConfig.getSnowId();
        ReportInfo reportInfo = helper.getReportInfo(reportInfoId);
        helper.checkData(reportInfo,new Generic<>(withdrawalReportDTO));

        //  施工状态  默认为非占道施工
        ConstructionStatusEnum constructionStatusEnum = ConstructionStatusEnum.CONSTRUCTION;
        //  获取未提交撤场上报的占道报备数据
        List<JeevesReportVO> jeevesReportVOList = jeevesReportMapper.selectNotSubmitWithdrawalJeevesReportList(new JeevesReportSO(reportInfo.getReportInfoId()));
        //  1整个项目施工结束
        if(1 == endProject){
            if(!CollectionUtils.isEmpty(jeevesReportVOList) && jeevesReportVOList.size() !=1){
                throw new ServiceException("还有未提交撤场上报的占道报备数据!");
            }
            constructionStatusEnum = ConstructionStatusEnum.WITHDRAWAL;
        }else{
            // 阶段性施工结束
            //  判断当前项目占道列表，是否有未提交撤场上报的单子，并且当前时间大于占道上报起点时间
            for (JeevesReportVO jeevesReportVO : jeevesReportVOList) {
                if(new Date().after(jeevesReportVO.getJeevesStartDate()) && !jeevesReportVO.getJeevesReportId().equals(jeevesReportId)){
                    constructionStatusEnum = constructionStatusEnum.ROAD_CONSTRUCTION;
                    break;
                }
            }
        }
        //  更新施工状态
        helper.updateReportConstructionStatus(reportInfo,constructionStatusEnum);

        withdrawalReport.setDeptId(reportInfo.getDeptId());
        withdrawalReport.setReviewedBy(reportInfo.getReviewedBy());

        //  附件信息
        String withdrawalFile = withdrawalReportDTO.getWithdrawalFile();
        long withdrawalFileId = snowIdConfig.getSnowId();
        if(StringUtils.isNotEmpty(withdrawalFile)){
            fileHelper.saveBusinessFileData(withdrawalFile,withdrawalFileId);
        }

        //  发送消息
        MsgTemplateDTO msgTemplateDTO = new MsgTemplateDTO(MsgTemplateEnum.TEMPLATE_CCSB,SecurityUtils.getUserId(), Longs.asList(reportInfo.getReviewedBy()));
        String p1 = SecurityUtils.getLoginUser().getUser().getNickName();
        String p2 = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss");
        String p3 = reportInfo.getProjectName();
        String p4 = DateUtils.dateTime(withdrawalReport.getWithdrawalTime());
        helper.saveMsg(msgTemplateDTO,p1,p2,p3,p4);


        //生成检查单
        helper.saveTask(reportInfoId,constructionStatusEnum.getCode(), BasicInfoTemplateEnum.INS_WITHDRAWAL_REPORT.getTbName(),withdrawalReportId,withdrawalReportDTO.getWithdrawalTime(),reportInfo.getDeptId());
        withdrawalReport.setWithdrawalReportId(withdrawalReportId);
        withdrawalReport.setWithdrawalFileId(withdrawalFileId);

        return withdrawalReportMapper.insert(withdrawalReport);
    }

    /**
     * 修改撤场上报
     *
     * @param withdrawalReportDTO 撤场上报
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateWithdrawalReport(WithdrawalReportDTO withdrawalReportDTO)
    {
        final Long withdrawalReportId = withdrawalReportDTO.getWithdrawalReportId();
        if(null == withdrawalReportId){
            throw new ServiceException("withdrawalReportId 不能为空!");
        }
        WithdrawalReport withdrawalReport = new WithdrawalReport();
        BeanUtils.copyProperties(withdrawalReportDTO,withdrawalReport);
        //更新附件信息
        String withdrawalFile = withdrawalReportDTO.getWithdrawalFile();
        WithdrawalReport _withdrawalReport = withdrawalReportMapper.selectById(withdrawalReportId);
        fileHelper.updateBusinessFileData(withdrawalFile,_withdrawalReport.getWithdrawalFileId());
        return withdrawalReportMapper.updateById(withdrawalReport);
    }

    /**
     * 批量删除撤场上报
     *
     * @param withdrawalReportIds 需要删除的撤场上报主键
     * @return 结果
     */
    @Override
    public int deleteWithdrawalReportByWithdrawalReportIds(Long[] withdrawalReportIds)
    {
        return withdrawalReportMapper.deleteWithdrawalReportByWithdrawalReportIds(withdrawalReportIds);
    }

    /**
     * 删除撤场上报信息
     *
     * @param withdrawalReportId 撤场上报主键
     * @return 结果
     */
    @Override
    public int deleteWithdrawalReportByWithdrawalReportId(Long withdrawalReportId)
    {
        return withdrawalReportMapper.deleteWithdrawalReportByWithdrawalReportId(withdrawalReportId);
    }
}
